home *** CD-ROM | disk | FTP | other *** search
- /*
- * devTtyAttach.c --
- *
- * This file manages the configuration of Z8530 chips on Sun-3
- * and Sun-4 workstations, and provides glue to attach the device
- * drivers for those chips to standard Sprite devices like
- * /dev/console and /dev/serialA.
- *
- * Copyright 1989 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4.md/devTtyAttach.c,v 9.7 91/10/18 01:21:50 dlong Exp $ SPRITE (Berkeley)";
- #endif /* not lint */
-
- #include "sprite.h"
- #include "stdio.h"
- #include "console.h"
- #include "devAddrs.h"
- #include "mouse.h"
- #include "mach.h"
- #include "machMon.h"
- #include "tty.h"
- #include "z8530.h"
- #ifndef sun2
- #include <sys/types.h>
- #include <mon/eeprom.h>
- #endif
-
- /*
- * Forward references to procedures declared in this file:
- */
-
- static int NullOutputChar();
- static int TtyInterrupt();
-
- #ifdef sun4c
-
- /*
- * Virtual addresses for serial device registers, extracted
- * from PROM.
- */
-
- static DevZ8530Device *zsAddr[2] = {
- (DevZ8530Device *)NIL, (DevZ8530Device *)NIL
- };
- static MachDevIntr zsIntr[2] = {{12, 0}, {12, 0}};
-
- #endif
-
- /*
- * Pre-initialized data structures for three of the four channels in
- * the two Z8530 SCC chips (see devMouse.c for the fourth).
- */
-
- static DevTty ttys[3];
-
- static DevZ8530 keyboard = {
- "keyboard", /* name */
- #ifdef sun4c
- (DevZ8530Device *) NIL, /* address */
- #else
- (DevZ8530Device *) DEV_KBD_ADDR, /* address */
- #endif
- &ttys[0], /* ttyPtr */
- #ifdef sun4c
- 0, /* vector */
- #else
- DEV_UART_VECTOR, /* vector */
- #endif
- 1200, /* baud */
- WRITE3_RX_8BIT, /* wr3 */
- WRITE5_TX_8BIT, /* wr5 */
- DevConsoleInputProc, /* inputProc */
- (ClientData) &ttys[0], /* inputData */
- NullOutputChar, /* outputProc */
- (ClientData) &ttys[0], /* outputData */
- 0, /* oldRr0 */
- Z_CHANNEL_A | Z_INACTIVE /* flags */
- };
-
- static DevZ8530 serialA = {
- "serialA", /* name */
- #ifdef sun4c
- (DevZ8530Device *) NIL, /* address */
- #else
- (DevZ8530Device *) DEV_SERIALA_ADDR, /* address */
- #endif
- &ttys[1], /* ttyPtr */
- #ifdef sun4c
- 0, /* vector */
- #else
- DEV_UART_VECTOR, /* vector */
- #endif
- 9600, /* baud */
- WRITE3_RX_8BIT, /* wr3 */
- WRITE5_TX_8BIT, /* wr5 */
- DevTtyInputChar, /* inputProc */
- (ClientData) &ttys[1], /* inputData */
- DevTtyOutputChar, /* outputProc */
- (ClientData) &ttys[1], /* outputData */
- 0, /* oldRr0 */
- Z_CHANNEL_A | Z_INACTIVE /* flags */
- };
-
- static DevZ8530 serialB = {
- "serialB", /* name */
- #ifdef sun4c
- (DevZ8530Device *) NIL, /* address */
- #else
- (DevZ8530Device *) DEV_SERIALB_ADDR, /* address */
- #endif
- &ttys[2], /* ttyPtr */
- #ifdef sun4c
- 0, /* vector */
- #else
- DEV_UART_VECTOR, /* vector */
- #endif
- 9600, /* baud */
- WRITE3_RX_8BIT, /* wr3 */
- WRITE5_TX_8BIT, /* wr5 */
- DevTtyInputChar, /* inputProc */
- (ClientData) &ttys[2], /* inputData */
- DevTtyOutputChar, /* outputProc */
- (ClientData) &ttys[2], /* outputData */
- 0, /* oldRr0 */
- Z_CHANNEL_B | Z_INACTIVE /* flags */
- };
-
- /*
- * The following variable is filled in with the unit that should
- * be used whenever "/dev/console" is opened (may be a serial unit
- * if the machine doesn't have a keyboard+display).
- */
-
- static int consoleUnit = 0;
-
- #ifdef sun4c
- # include <string.h>
-
- static int
- GetZSAddr(node, name, clientData)
- unsigned int node;
- char *name;
- struct ConfigBuf *clientData;
- {
- int which;
- struct config_ops *configPtr;
-
- if (strcmp(name,"zs") == 0) {
- configPtr = romVectorPtr->v_config_ops;
- if (configPtr->devr_getproplen(node, "keyboard") != -1) {
- which = 1;
- } else {
- which = 0;
- }
- configPtr->devr_getprop(node, "address", &zsAddr[which]);
- configPtr->devr_getprop(node, "intr", &zsIntr[which]);
- Mach_MonPrintf("PROM: address zs %d %x intr %d\n",
- which, zsAddr[which], zsIntr[which].pri);
- return zsAddr[0] != (DevZ8530Device *)NIL &&
- zsAddr[1] != (DevZ8530Device *)NIL;
- } else {
- return 0;
- }
- }
- #endif
-
- /*
- *----------------------------------------------------------------------
- *
- * DevTtyInit --
- *
- * Called during bootstrapping to initialize terminal-related
- * things.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Resets serial devices and performs other initialization.
- *
- *----------------------------------------------------------------------
- */
-
- void
- DevTtyInit()
- {
- char promConsoleType;
-
- /*
- * Figure out whether this machine has a display for a console or
- * just a terminal on a serial line.
- */
-
- #ifndef sun2
- #ifdef sun4c
- promConsoleType = *romVectorPtr->inSource;
- #else
- promConsoleType = ((struct eeprom *) EEPROM_BASE)->ee_diag.eed_console;
- #endif /* sun4c */
- switch (promConsoleType) {
- #ifdef sun4c
- case INUARTA:
- #else
- case EED_CONS_TTYA:
- #endif
- consoleUnit = 1;
- break;
- #ifdef sun4c
- case INUARTB:
- #else
- case EED_CONS_TTYB:
- #endif
- consoleUnit = 2;
- break;
- #ifdef sun4c
- case INKEYB:
- #else
- case EED_CONS_BW:
- case EED_CONS_COLOR:
- case EED_CONS_P4:
- #endif
- consoleUnit = 0;
- break;
- default:
- printf("Warning: %s 0x%x\n",
- "Dev_TtyAttach couldn't identify console type",
- promConsoleType);
- break;
- }
- #endif /* sun2 */
-
- /*
- * Reset the devices.
- */
-
- #ifdef sun4c
- Mach_MonTraverseDevTree(0, GetZSAddr, (void *)NIL);
- keyboard.address = (DevZ8530Device *) &zsAddr[1][1];
- serialA.address = (DevZ8530Device *) &zsAddr[0][1];
- serialB.address = (DevZ8530Device *) &zsAddr[0][0];
- keyboard.vector = zsIntr[1].pri;
- serialA.vector = serialB.vector = zsIntr[0].pri;
- #endif
- DevZ8530RawProc((Address)&keyboard, TD_RAW_SHUTDOWN, 0, (char *) NULL,
- 0, (char *) NULL);
- DevZ8530RawProc((Address)&serialA, TD_RAW_SHUTDOWN, 0, (char *) NULL,
- 0, (char *) NULL);
- DevZ8530RawProc((Address)&serialB, TD_RAW_SHUTDOWN, 0, (char *) NULL,
- 0, (char *) NULL);
- #ifdef sun4c
- DevMouseInit((DevZ8530Device *)&zsAddr[1][0], zsIntr[1].pri);
- #else
- DevMouseInit();
- #endif
-
- #ifdef sun4
- #ifdef sun4c
- Mach_SetHandler(zsIntr[0].pri, TtyInterrupt, (ClientData) 0);
- Mach_SetHandler(zsIntr[1].pri, TtyInterrupt, (ClientData) 0);
- #else /* sun4c */
- Mach_SetHandler(12, TtyInterrupt, (ClientData) 0);
- #endif /* sun4c */
- #else /* sun4 */
- Mach_SetHandler(DEV_UART_VECTOR, TtyInterrupt, (ClientData) 0);
- #endif /* sun4 */
- Mach_MonStopNmi();
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * DevTtyAttach --
- *
- * Given a unit number, return the DevTty for the unit, properly
- * initialized. This procedure is called as part of the open
- * sequence for a terminal.
- *
- * Results:
- * The return value is a pointer to a DevTty for the given unit,
- * with some of its fields filled in (see devTty.h for details).
- * If the unit number is bad, then NULL is returned.
- *
- * Side effects:
- * Device-specific data structures get initialized.
- *
- *----------------------------------------------------------------------
- */
-
- DevTty *
- DevTtyAttach(unit)
- int unit; /* Unit number for device. */
- {
- register DevTty *ttyPtr;
-
- if ((unit > 2) || (unit < 0)) {
- return NULL;
- }
-
- /*
- * If the console is one of the serial units, then disallow the
- * serial unit for any use other than console. Otherwise the
- * wait tokens will get confused (two different wait tokens from
- * higher-level software, but only one stored in the tty structure).
- */
-
- if ((unit != 0) && (unit == consoleUnit)) {
- return NULL;
- }
-
- if (unit == 0) {
- unit = consoleUnit;
- }
- ttyPtr = &ttys[unit];
-
- /*
- * If the terminal is already open then there's nothing more to
- * do; otherwise, initialize the information relating to the
- * unit.
- */
-
- if (ttyPtr->openCount > 0) {
- return ttyPtr;
- }
- ttyPtr->rawProc = DevZ8530RawProc;
- ttyPtr->activateProc = DevZ8530Activate;
- ttyPtr->inputProc = (void (*)()) NIL;
- ttyPtr->inputData = (ClientData) 0;
- if (unit == consoleUnit) {
- ttyPtr->consoleFlags = DEV_TTY_IS_CONSOLE;
- } else {
- ttyPtr->consoleFlags = 0;
- }
-
- switch (unit) {
-
- /*
- * Unit 0 is the display+keyboard, which serves as console
- * if it exists.
- */
-
- case 0:
- ttyPtr->rawProc = DevConsoleRawProc;
- ttyPtr->rawData = (ClientData) &keyboard;
- break;
-
- /*
- * Unit 1 is serialA.
- */
-
- case 1:
- ttyPtr->rawData = (ClientData) &serialA;
- break;
-
- /*
- * Unit 2 is serialB.
- */
-
- case 2:
- ttyPtr->rawData = (ClientData) &serialB;
- break;
- }
- return ttyPtr;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * DevGrabKeyboard --
- *
- * This procedure is a special hack to allow events from the
- * keyboard to be redirected back and forth between /dev/console
- * and /dev/event. DevGrabKeyboard is called to redirect input
- * keystrokes away from their normal target (/dev/console) to
- * some other place.
- *
- * Results:
- * The return value is a pointer to the DevZ8530 structure for
- * the keyboard (in case the caller should need to use some of
- * its fields).
- *
- * Side effects:
- * From now on, inputProc will be used to process input characters
- * from the keyboard and outpuProc will be used to supply output
- * characters to the keyboard.
- *
- *----------------------------------------------------------------------
- */
-
- DevZ8530 *
- DevGrabKeyboard(inputProc, inputData, outputProc, outputData)
- void (*inputProc)(); /* Procedure for devTty.c to call
- * to process input characters
- * at background level. */
- ClientData inputData; /* Argument to pass to inputProc. */
- int (*outputProc)(); /* Interrupt-level procedure to
- * provide next output character. */
- ClientData outputData; /* Argument to pass to outputProc. */
- {
- ttys[0].inputProc = inputProc;
- ttys[0].inputData = inputData;
- keyboard.outputProc = outputProc;
- keyboard.outputData = outputData;
- return &keyboard;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * DevReleaseKeyboard --
- *
- * This procedure is also part of the special hack to allow events
- * from the keyboard to be redirected back and forth between
- * /dev/console and /dev/event. When the event device is closed
- * for the last time, this procedure is called to redirect keyboard
- * input back to /dev/console.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Keyboard input goes to /dev/console again.
- *
- *----------------------------------------------------------------------
- */
-
- void
- DevReleaseKeyboard()
- {
- ttys[0].inputProc = (void (*)()) NIL;
- ttys[0].inputData = (ClientData) 0;
- keyboard.outputProc = NullOutputChar;
- keyboard.outputData = (ClientData) &ttys[0];
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * TtyInterrupt --
- *
- * This procedure is called whenever an interrupt occurs on
- * one of the Z8530 chips. Various models of Sun's don't
- * handle "real" interrupt vectors from the UART chips, so the
- * safest thing is to auto-vector them all through this procedure.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Each chip's interrupt handler gets invoked in turn to
- * process input and output characters for that chip.
- *
- *----------------------------------------------------------------------
- */
-
- static int
- TtyInterrupt()
- {
- DevZ8530Interrupt((ClientData)&keyboard);
- DevZ8530Interrupt((ClientData)&serialA);
- DevZ8530Interrupt((ClientData)&serialB);
- DevMouseInterrupt();
- return 0;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NullOutputChar --
- *
- * This procedure is entered as the outputProc field of
- * DevZ8530 structures when the device is not used for
- * output.
- *
- * Results:
- * Always returns -1, which means "no output characters available".
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- /* ARGSUSED */
- static int
- NullOutputChar(clientData)
- ClientData clientData; /* Not used. */
- {
- return -1;
- }
-